import { Client } from "./mod.ts";
import { User } from "./user.ts";

/**
 * Organization represents a organization
 */
export interface Organization {
  id: number;
  username: string;
  full_name: string;
  avatar_url: string;
  description: string;
  website: string;
  location: string;
}

/**
 * Team represents a team in an organization
 */
export interface Team {
  id: number;
  name: string;
  description: string;
  permission: string;
}

/**
 * Options for creating an organization
 */
export interface CreateOrgOption {
  username: string;
  full_name?: string;
  description?: string;
  website?: string;
  location?: string;
}

/**
 * Options for editing an organization
 */
export interface EditOrgOption {
  full_name?: string;
  description?: string;
  website?: string;
  location?: string;
}

/**
 * Options for adding a member to an organization
 */
export interface AddOrgMembershipOption {
  role: string;
}

/**
 * Options for creating a team in an organization
 */
export interface CreateTeamOption {
  name: string;
  description?: string;
  permission?: string;
}

/**
 * Organization API endpoints
 */
export class OrganizationAPI {
  constructor(private client: Client) {}

  /**
   * List organizations the authenticated user belongs to
   */
  async listMyOrgs(): Promise<Organization[]> {
    return await this.client.doRequest<Organization[]>("GET", "/user/orgs");
  }

  /**
   * List organizations a user belongs to
   */
  async listUserOrgs(username: string): Promise<Organization[]> {
    return await this.client.doRequest<Organization[]>("GET", `/users/${username}/orgs`);
  }

  /**
   * Get an organization by name
   */
  async getOrg(orgname: string): Promise<Organization> {
    return await this.client.doRequest<Organization>("GET", `/orgs/${orgname}`);
  }

  /**
   * Create an organization
   */
  async createOrg(options: CreateOrgOption): Promise<Organization> {
    return await this.client.doRequest<Organization>(
      "POST",
      "/user/orgs",
      { "Content-Type": "application/json" },
      options
    );
  }

  /**
   * Ensure organization exists, create if not exists
   * @param orgname Organization name
   * @param options Optional organization details
   * @returns Organization info and whether it was newly created
   */
  async ensureOrgExists(
    orgname: string,
    options?: Omit<CreateOrgOption, 'username'>
  ): Promise<{ org: Organization; created: boolean }> {
    try {
      const org = await this.getOrg(orgname);
      return { org, created: false };
    } catch (error) {
      if (error instanceof Error && error.message.includes('404')) {
        const org = await this.createOrg({
          username: orgname,
          ...options
        });
        return { org, created: true };
      }
      throw error;
    }
  }

  /**
   * Edit an organization
   */
  async editOrg(orgname: string, options: EditOrgOption): Promise<void> {
    await this.client.doRequest<void>(
      "PATCH", 
      `/orgs/${orgname}`, 
      { "Content-Type": "application/json" },
      options
    );
  }

  // Team API

  /**
   * List teams in an organization
   */
  async listTeams(orgname: string): Promise<Team[]> {
    return await this.client.doRequest<Team[]>("GET", `/orgs/${orgname}/teams`);
  }

  /**
   * Create a team in an organization
   */
  async createTeam(orgname: string, options: CreateTeamOption): Promise<Team> {
    return await this.client.doRequest<Team>(
      "POST", 
      `/orgs/${orgname}/teams`, 
      { "Content-Type": "application/json" },
      options
    );
  }

  // Member API

  /**
   * Add a user to an organization
   */
  async addOrgMembership(orgname: string, username: string, options: AddOrgMembershipOption): Promise<void> {
    await this.client.doRequest<void>(
      "PUT", 
      `/orgs/${orgname}/membership/${username}`, 
      { "Content-Type": "application/json" },
      options
    );
  }
} 